/*******************************************************************************
 *                                    ZLG
 *                         ----------------------------
 *                         innovating embedded platform
 *
 * Copyright (c) 2001-present Guangzhou ZHIYUAN Electronics Co., Ltd.
 * All rights reserved.
 *
 * Contact information:
 * web site:    https://www.zlg.cn
 *******************************************************************************/
#ifndef __HPM6450_REGS_CLK_H
#define __HPM6450_REGS_CLK_H

#ifdef __cplusplus
extern "C" {
#endif  /* __cplusplus*/
#include "core/include/hpm6e00_regs_base.h"
#include <stdint.h>

/* \brief HPM 系统控制寄存器定义 */
typedef struct {
    volatile uint32_t           RESOURCE[380];           /* 0x0 - 0x5EC: Resource control register for cpu0_core */
    volatile const uint8_t      RESERVED0[528];          /* 0x5F0 - 0x7FF: Reserved */
    struct {
        volatile uint32_t       VALUE;                   /* 0x800: Group setting */
        volatile uint32_t       SET;                     /* 0x804: Group setting */
        volatile uint32_t       CLEAR;                   /* 0x808: Group setting */
        volatile uint32_t       TOGGLE;                  /* 0x80C: Group setting */
    } GROUP0[4];
    struct {
        volatile uint32_t       VALUE;                   /* 0x840: Group setting */
        volatile uint32_t       SET;                     /* 0x844: Group setting */
        volatile uint32_t       CLEAR;                   /* 0x848: Group setting */
        volatile uint32_t       TOGGLE;                  /* 0x84C: Group setting */
    } GROUP1[4];
    volatile const uint8_t      RESERVED1[128];          /* 0x880 - 0x8FF: Reserved */
    struct {
        volatile uint32_t       VALUE;                   /* 0x900: Affiliate of Group */
        volatile uint32_t       SET;                     /* 0x904: Affiliate of Group */
        volatile uint32_t       CLEAR;                   /* 0x908: Affiliate of Group */
        volatile uint32_t       TOGGLE;                  /* 0x90C: Affiliate of Group */
    } AFFILIATE[2];
    struct {
        volatile uint32_t       VALUE;                   /* 0x920: Retention Contol */
        volatile uint32_t       SET;                     /* 0x924: Retention Contol */
        volatile uint32_t       CLEAR;                   /* 0x928: Retention Contol */
        volatile uint32_t       TOGGLE;                  /* 0x92C: Retention Contol */
    } RETENTION[2];
    volatile const uint8_t      RESERVED2[1728];         /* 0x940 - 0xFFF: Reserved */
    struct {
        volatile uint32_t       STATUS;                  /* 0x1000: Power Setting */
        volatile uint32_t       LF_WAIT;                 /* 0x1004: Power Setting */
        volatile const uint8_t  RESERVED0[4];            /* 0x1008 - 0x100B: Reserved */
        volatile uint32_t       OFF_WAIT;                /* 0x100C: Power Setting */
    } POWER[3];
    volatile const uint8_t      RESERVED3[976];          /* 0x1030 - 0x13FF: Reserved */
    struct {
        volatile uint32_t       CONTROL;                 /* 0x1400: Reset Setting */
        volatile uint32_t       CONFIG;                  /* 0x1404: Reset Setting */
        volatile const uint8_t  RESERVED0[4];            /* 0x1408 - 0x140B: Reserved */
        volatile uint32_t       COUNTER;                 /* 0x140C: Reset Setting */
    } RESET[4];
    volatile const uint8_t      RESERVED4[960];          /* 0x1440 - 0x17FF: Reserved */
    volatile uint32_t           CLOCK[73];               /* 0x1800 - 0x1920: Clock setting */
    volatile const uint8_t      RESERVED5[732];          /* 0x1924 - 0x1BFF: Reserved */
    volatile uint32_t           ADCCLK[4];               /* 0x1C00 - 0x1C0C: Clock setting */
    volatile uint32_t           I2SCLK[2];               /* 0x1C10 - 0x1C14: Clock setting */
    volatile const uint8_t      RESERVED6[1000];         /* 0x1C18 - 0x1FFF: Reserved */
    volatile uint32_t           GLOBAL00;                /* 0x2000: Clock senario */
    volatile const uint8_t      RESERVED7[1020];         /* 0x2004 - 0x23FF: Reserved */
    struct {
        volatile uint32_t       CONTROL;                 /* 0x2400: Clock measure and monitor control */
        volatile const uint32_t CURRENT;                 /* 0x2404: Clock measure result */
        volatile uint32_t       LOW_LIMIT;               /* 0x2408: Clock lower limit */
        volatile uint32_t       HIGH_LIMIT;              /* 0x240C: Clock upper limit */
        volatile const uint8_t  RESERVED0[16];           /* 0x2410 - 0x241F: Reserved */
    } MONITOR[4];
    volatile const uint8_t      RESERVED8[896];          /* 0x2480 - 0x27FF: Reserved */
    struct {
        volatile uint32_t       LP;                      /* 0x2800: CPU0 LP control */
        volatile uint32_t       LOCK;                    /* 0x2804: CPU0 Lock GPR */
        volatile uint32_t       GPR[14];                 /* 0x2808 - 0x283C: CPU0 GPR0 */
        volatile const uint32_t WAKEUP_STATUS[6];        /* 0x2840 - 0x2854: CPU0 wakeup IRQ status */
        volatile const uint8_t  RESERVED0[40];           /* 0x2858 - 0x287F: Reserved */
        volatile uint32_t       WAKEUP_ENABLE[6];        /* 0x2880 - 0x2894: CPU0 wakeup IRQ enable */
        volatile const uint8_t  RESERVED1[872];          /* 0x2898 - 0x2BFF: Reserved */
    } CPU[2];
} hpm_sys_ctl_t;

#define HPM_SYS_CTL  ((hpm_sys_ctl_t *)HPM_SYSCTL_BASE)

/* \brief 时钟源忙定义 */
#define SYSCTL_RESOURCE_LOC_BUSY_MASK      (0x40000000UL)
#define SYSCTL_RESOURCE_LOC_BUSY_POS       (30U)
#define SYSCTL_RESOURCE_LOC_BUSY_GET(x)  (((uint32_t)(x) & SYSCTL_RESOURCE_LOC_BUSY_MASK) >> SYSCTL_RESOURCE_LOC_BUSY_POS)

/* \brief 时钟忙定义 */
#define SYSCTL_CLOCK_LOC_BUSY_MASK         (0x40000000UL)
#define SYSCTL_CLOCK_LOC_BUSY_POS          (30U)
#define SYSCTL_CLOCK_LOC_BUSY_GET(x)     (((uint32_t)(x) & SYSCTL_CLOCK_LOC_BUSY_MASK) >> SYSCTL_CLOCK_LOC_BUSY_POS)

/* \brief 时钟源定义 */
#define SYSCTL_CLOCK_MUX_MASK              (0x700U)
#define SYSCTL_CLOCK_MUX_POS               (8U)
#define SYSCTL_CLOCK_MUX_SET(x)          (((uint32_t)(x) << SYSCTL_CLOCK_MUX_POS) & SYSCTL_CLOCK_MUX_MASK)
#define SYSCTL_CLOCK_MUX_GET(x)          (((uint32_t)(x) & SYSCTL_CLOCK_MUX_MASK) >> SYSCTL_CLOCK_MUX_POS)

/* \brief 时钟分频定义 */
#define SYSCTL_CLOCK_DIV_MASK              (0xFFU)
#define SYSCTL_CLOCK_DIV_POS               (0U)
#define SYSCTL_CLOCK_DIV_SET(x)          (((uint32_t)(x) << SYSCTL_CLOCK_DIV_POS) & SYSCTL_CLOCK_DIV_MASK)
#define SYSCTL_CLOCK_DIV_GET(x)          (((uint32_t)(x) & SYSCTL_CLOCK_DIV_MASK) >> SYSCTL_CLOCK_DIV_POS)

typedef struct {
    volatile uint32_t XTAL;                        /* 0x0: OSC configuration */
    volatile const  uint8_t  RESERVED0[124];              /* 0x4 - 0x7F: Reserved */
    struct {
        volatile uint32_t MFI;                     /* 0x80: PLL0 multiple register */
        volatile uint32_t MFN;                     /* 0x84: PLL0 fraction numerator register */
        volatile uint32_t MFD;                     /* 0x88: PLL0 fraction demoninator register */
        volatile uint32_t SS_STEP;                 /* 0x8C: PLL0 spread spectrum step register */
        volatile uint32_t SS_STOP;                 /* 0x90: PLL0 spread spectrum stop register */
        volatile uint32_t CONFIG;                  /* 0x94: PLL0 confguration register */
        volatile uint32_t LOCKTIME;                /* 0x98: PLL0 lock time register */
        volatile uint32_t STEPTIME;                /* 0x9C: PLL0 step time register */
        volatile uint32_t      ADVANCED;                /* 0xA0: PLL0 advance configuration register */
        volatile const uint8_t RESERVED0[28];           /* 0xA4 - 0xBF: Reserved */
        volatile uint32_t      DIV[3];                  /* 0xC0 - 0xC8: PLL0 divider output 0 configuration register */
        volatile const uint8_t RESERVED1[52];           /* 0xCC - 0xFF: Reserved */
    } PLL[3];
} hpm_pll_ctlv2_t;

#define HPM_PLL_CTLV2  ((hpm_pll_ctlv2_t *)HPM_PLLCTLV2_BASE)

/* \brief MFI 定义， F = Fref * (MFI + MFN / MFD) */
#define PLLCTLV2_PLL_MFI_MFI_MASK         (0x7FU)
#define PLLCTLV2_PLL_MFI_MFI_POS          (0U)
#define PLLCTLV2_PLL_MFI_MFI_SET(x)     (((uint32_t)(x) << PLLCTLV2_PLL_MFI_MFI_POS) & PLLCTLV2_PLL_MFI_MFI_MASK)
#define PLLCTLV2_PLL_MFI_MFI_GET(x)     (((uint32_t)(x) & PLLCTLV2_PLL_MFI_MFI_MASK) >> PLLCTLV2_PLL_MFI_MFI_POS)

/* \brief MFN 定义， F = Fref * (MFI + MFN / MFD) */
#define PLLCTLV2_PLL_MFN_MFN_MASK         (0x3FFFFFFFUL)
#define PLLCTLV2_PLL_MFN_MFN_POS          (0U)
#define PLLCTLV2_PLL_MFN_MFN_SET(x)     (((uint32_t)(x) << PLLCTLV2_PLL_MFN_MFN_POS) & PLLCTLV2_PLL_MFN_MFN_MASK)
#define PLLCTLV2_PLL_MFN_MFN_GET(x)     (((uint32_t)(x) & PLLCTLV2_PLL_MFN_MFN_MASK) >> PLLCTLV2_PLL_MFN_MFN_POS)

/* \brief MFD 定义， F = Fref * (MFI + MFN / MFD) */
#define PLLCTLV2_PLL_MFD_MFD_MASK         (0x3FFFFFFFUL)
#define PLLCTLV2_PLL_MFD_MFD_POS          (0U)
#define PLLCTLV2_PLL_MFD_MFD_SET(x)     (((uint32_t)(x) << PLLCTLV2_PLL_MFD_MFD_POS) & PLLCTLV2_PLL_MFD_MFD_MASK)
#define PLLCTLV2_PLL_MFD_MFD_GET(x)     (((uint32_t)(x) & PLLCTLV2_PLL_MFD_MFD_MASK) >> PLLCTLV2_PLL_MFD_MFD_POS)

/* \brief 分频因子定义 */
#define PLLCTLV2_PLL_DIV_DIV_MASK         (0x3FU)
#define PLLCTLV2_PLL_DIV_DIV_POS          (0U)
#define PLLCTLV2_PLL_DIV_DIV_SET(x)     (((uint32_t)(x) << PLLCTLV2_PLL_DIV_DIV_POS) & PLLCTLV2_PLL_DIV_DIV_MASK)
#define PLLCTLV2_PLL_DIV_DIV_GET(x)     (((uint32_t)(x) & PLLCTLV2_PLL_DIV_DIV_MASK) >> PLLCTLV2_PLL_DIV_DIV_POS)
#ifdef __cplusplus
}
#endif  /* __cplusplus  */
#endif

